#ifndef __SUPERVISOR_H_INCLUDED__
#define __SUPERVISOR_H_INCLUDED__

#include "command.h"
#include "json.h"
#include "mongoose.h"

class Supervisor {
  enum EMethod { GET = 0, POST };

  typedef void (Supervisor::*Proc)(mg_connection *pConn,
                                   const Json::Value &rParam);

  typedef struct Processor {
    EMethod emMethod;
    Proc fProc;
  } Processor;

public:
  Supervisor() : _iMgr(), _iConf(), _pAuth(nullptr) {}

  static void Dispatch(mg_connection *pConn, int nEvent, void *pData);

  void Start(Command &rCmd);
  void Breath();

  bool CheckConnect(mg_connection *pConn);
  bool CheckAuth(mg_connection *pConn, http_message *pMsg);

  void ResponseClose(mg_connection *pConn);
  void ResponseResource(mg_connection *pConn, const std::string &sPath);
  void ResponseWebsocketOpened(mg_connection *pConn, const std::string &sUrl);
  void ResponseApi(mg_connection *pConn, http_message *pMsg);
  void ResponseNeedAuth(mg_connection *pConn);

  void Reload(mg_connection *pConn, const Json::Value &rParam);
  void AddWatcher(mg_connection *pConn, const Json::Value &rParam);
  void EditWatcher(mg_connection *pConn, const Json::Value &rParam);
  void StartWatcher(mg_connection *pConn, const Json::Value &rParam);
  void StopWatcher(mg_connection *pConn, const Json::Value &rParam);
  void DeleteWatcher(mg_connection *pConn, const Json::Value &rParam);

private:
  bool LoadSetting();
  void SaveSetting();

  void Register(const std::string &sUrl, EMethod emMethod, Proc fProc);

  Json::Value Url2Json(const char *pData, size_t nSize);
  Json::Value GetWatcherInfo(const std::string &sName);
  Json::Value GetConf(const std::string &sName);

  void Response(mg_connection *pConn, int nHttpCode, const std::string &sHeader,
                const std::string &sContent);
  void Broadcast(const std::string &sScope, const std::string &sJson);

private:
  mg_mgr _iMgr;
  Json::Value _iConf;
  FILE *_pAuth;

  std::vector<mg_connection *> _vSockets;
  std::map<std::string, Processor> _mApis;
};

#endif //!	__SUPERVISOR_H_INCLUDED__